import 'dart:async';

import 'package:flutter/material.dart';
import 'package:lib_wallet_connect/utils/chain_data.dart';
import 'package:lib_wallet_connect/utils/chain_metadata.dart';
import 'package:walletconnect_flutter_v2/apis/core/core.dart';
import 'package:walletconnect_flutter_v2/apis/core/pairing/utils/pairing_models.dart';
import 'package:walletconnect_flutter_v2/apis/core/relay_client/relay_client_models.dart';
import 'package:walletconnect_flutter_v2/apis/core/store/store_models.dart';
import 'package:walletconnect_flutter_v2/apis/sign_api/models/session_models.dart';
import 'package:walletconnect_flutter_v2/apis/sign_api/models/sign_client_events.dart';
import 'package:walletconnect_flutter_v2/apis/utils/constants.dart';
import 'package:walletconnect_flutter_v2/apis/utils/log_level.dart';
import 'package:walletconnect_flutter_v2/apis/web3wallet/web3wallet.dart';
abstract class WCServiceWidget{
  Web3Wallet? _web3Wallet;

  static Web3Wallet? instance;
  final projectId = '10a7c84999cb867f5549ee06db9ae074';

  final PairingMetadata  metadata = const  PairingMetadata(
    name: 'Kai Wallet',
    description: 'WalletConnect\'s sample wallet with Flutter',
    url: 'https://walletconnect.com/',
    icons: [
      'https://docs.walletconnect.com/assets/images/web3walletLogo-54d3b546146931ceaf47a3500868a73a.png'
    ],
    redirect: Redirect(
      native: 'kai://',
      universal: 'https://walletconnect.com',
    ),
  );

  static onPair(String key) async {
    final Uri uriData = Uri.parse(key);
    await instance!.pair(uri: uriData);
  }

  Web3Wallet? get getWeb3Wallet=> _web3Wallet;

  // 支持的方法
  Map<String, dynamic Function(String, dynamic)> get methodRequestHandlers => {
        'personal_sign': personalSign,
        'eth_sign': ethSign,
        'eth_signTransaction': ethSignTransaction,
        'eth_sendTransaction': ethSendTransaction,
        'eth_signTypedData': ethSignTypedData,
        'eth_signTypedData_v4': ethSignTypedDataV4,
        'wallet_switchEthereumChain': switchChain,
        'wallet_addEthereumChain': addChain,
      };

  //  创建 链接 ，设置 服务端支持配置参数
  Future<Web3Wallet?> createWcc() async {
    // Create the web3wallet
    _web3Wallet = Web3Wallet(
      core: Core(
        projectId: projectId,
        logLevel: LogLevel.error,
      ),
      metadata: metadata ,
    );
    await Web3Wallet.createInstance(projectId: projectId, metadata: metadata);
    debugPrint('_web3Wallet ${_web3Wallet}');
    instance = _web3Wallet;
    List<String> keys = ChainData.mainChains.map((e) => e.chainId).toList();
    for (final chainId in keys) {
      _web3Wallet!.registerAccount(
        chainId: chainId,
        // 0x8e325b68e7af42f3c21dbc4611cbe9268c0d328c
        // 0xE2BE444EF66780A7D5b5A81604229935B99823FA
        accountAddress: "0x16A886f77Cafe476a51A954b273c36B9422F0309",
      );

      for (var handler in methodRequestHandlers.entries) {
        _web3Wallet!.registerRequestHandler(
          chainId: chainId,
          method: handler.key,
          handler: handler.value,
        );
      }

      for (final event in EventsConstants.requiredEvents) {
        _web3Wallet!.registerEventEmitter(
          chainId: chainId,
          event: event,
        );
      }
    }

    // Setup our listeners
    debugPrint('web3wallet create');
    _web3Wallet!.core.pairing.onPairingInvalid.subscribe(onPairingInvalid);
    _web3Wallet!.core.pairing.onPairingCreate.subscribe(onPairingCreate);
    _web3Wallet!.pairings.onSync.subscribe(_onPairingsSync);
    // 扫码验证
    _web3Wallet!.onSessionProposal.subscribe(onSessionProposal);
    _web3Wallet!.onSessionProposalError.subscribe(_onSessionProposalError);
    // _web3Wallet!.onAuthRequest.subscribe(onAuthRequest);
    _web3Wallet!.core.relayClient.onRelayClientError
        .subscribe(_onRelayClientError);
    _web3Wallet!.onSessionRequest.subscribe(onSessionRequest);
    _web3Wallet!.init();
    return _web3Wallet!;
  }

  void init() {
    debugPrint('web3wallet init');
    _web3Wallet!.init();
  }

  FutureOr onDispose() {
    debugPrint('web3wallet dispose');
    _web3Wallet!.core.pairing.onPairingInvalid.unsubscribe(onPairingInvalid);
    _web3Wallet!.pairings.onSync.unsubscribe(_onPairingsSync);
    _web3Wallet!.onSessionProposal.unsubscribe(onSessionProposal);
    _web3Wallet!.onSessionProposalError.unsubscribe(_onSessionProposalError);
    // _web3Wallet!.onAuthRequest.unsubscribe(onAuthRequest);
    _web3Wallet!.core.relayClient.onRelayClientError
        .unsubscribe(_onRelayClientError);
    if(_web3Wallet!=null){
      _web3Wallet=null;
    }
  }



  void _onPairingsSync(StoreSyncEvent? args) {
    if (args != null) {
      // pairings.value = _web3Wallet!.pairings.getAll();
    }
  }

  void _onRelayClientError(ErrorEvent? args) {
    debugPrint('[$runtimeType] _onRelayClientError ${args?.error}');
  }

  void _onSessionProposalError(SessionProposalErrorEvent? args) async {
    debugPrint('[$runtimeType] _onSessionProposalError $args');
    if (args != null) {
      String errorMessage = args.error.message;
      if (args.error.code == 5100) {
        errorMessage =
            errorMessage.replaceFirst('Requested:', '\n\nRequested:');
        errorMessage =
            errorMessage.replaceFirst('Supported:', '\n\nSupported:');
      }
    }
  }

  Map<String, Namespace> generateNamespaces(
    Map<String, Namespace>? approvedNamespaces,
    WCChainType chainType, {required String account}
  ) {
    //
    final constructedNS = Map<String, Namespace>.from(approvedNamespaces ?? {});
    List<String> accountList = [];
    if(constructedNS[chainType.name]!.accounts.isNotEmpty){
      accountList =   constructedNS[chainType.name]!.accounts.map((e){
        List<String> keys = e.split(':');
        String key = keys[0]+ keys[1]+ account;
        return key;
      }).toList();
    }
    constructedNS[chainType.name] = constructedNS[chainType.name]!.copyWith(
      methods: [
        'personal_sign',
        ...constructedNS[chainType.name]!.methods,
      ],
      accounts: accountList,
    );
    return constructedNS;
  }

  void onSessionProposal(SessionProposalEvent? args) async {
    print('yanzheng');
  }

  void onPairingInvalid(PairingInvalidEvent? args) {
    debugPrint('[$runtimeType] _onPairingInvalid $args');
  }

  void onPairingCreate(PairingEvent? args) {
    debugPrint('[$runtimeType] _onPairingCreate $args');
  }

   void onSessionRequest(SessionRequestEvent? args) async {}

  // personal_sign is handled using onSessionRequest event for demo purposes
   Future<void> personalSign(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] personalSign request: $parameters');
  }

  Future<void> ethSign(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] ethSign request: $parameters');
  }

  Future<void> ethSignTypedData(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] ethSignTypedData request: $parameters');
  }

  Future<void> ethSignTypedDataV4(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] ethSignTypedDataV4 request: $parameters');
  }

  Future<void> ethSignTransaction(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] ethSignTransaction request: $parameters');
  }

  Future<void> ethSendTransaction(String topic, dynamic parameters) async {
    debugPrint('[$runtimeType] ethSendTransaction request: $parameters');
  }

  Future<void> switchChain(String topic, dynamic parameters) async {
    debugPrint('received switchChain request: $topic $parameters');
  }

  Future<void> addChain(String topic, dynamic parameters) async {
    debugPrint('received addChain request: $topic $parameters');
  }

}
